package com.foo.designpattern.prototype;

import junit.framework.TestCase;

import java.io.IOException;

/**
 * com.foo.designpattern.prototype
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-04-27 0:08.
 *
 * @Description 测试类：原型模式
 * 网上的例子中选取了齐天大圣身外身法术的例子，并有浅克隆和深克隆两种克隆方式
 */
public class PrototypeTestCase extends TestCase {
    // 鼠标光标停留在不同的位置可以测试不同的方法
    Monkey monkey = new Monkey();

    /**
     * 测试浅克隆(浅拷贝)
     */
    public void testPrototype() {
        System.out.println("===========↓↓↓原型模式：浅克隆，测试开始↓↓↓===========");

        Monkey copyMonkey = (Monkey) monkey.clone();
        System.out.println("大圣本尊的生日是：" + monkey.getBirthDate());
        System.out.println("浅克隆大圣的生日是：" + copyMonkey.getBirthDate());
        // ==和equals方法的区别？
        /**
         * ==操作符专门用来比较两个变量的值是否相等，也就是用于比较变量所对应的内存中所存储的数值是否相同，要比较两个基本类型的数据或两个引用变量是否相等，只能用==操作符。
         * equals方法是用于比较两个对立对象的内容是否相同，就好比去比较两个人的长相是否相同，它比较的两个对象是独立的。
         * 例子：String a = new String("foo");和String b = new String("foo");
         * 两条new语句创建了两个对象，然后用a,b两个变量分别指向了他们，这是两个不同的对象，他们的首地址是不同的，即a和b中存储的数值是不同的，所以，表达式a==b将返回false;
         * 而这两个对象中的内容是相同的，所以，表达式a.equals(b)将返回true。
         */
        System.out.println("大圣本尊和浅克隆大圣是否为同一个对象? " + (monkey == copyMonkey));
        // 浅克隆中引用的对象不进行克隆，仍然指向原来的对象，所以本尊和克隆体拿个同一个金箍棒。
        System.out.println("大圣本尊的金箍棒和浅克隆大圣的金箍棒是否为同一个对象? " + (monkey.getGoldRingedStaff() == copyMonkey.getGoldRingedStaff()));

        System.out.println("= = = = ↑↑↑原型模式：浅克隆，测试结束↑↑↑ = = = =");
    }

    /**
     * 测试深克隆(深拷贝)
     *
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public void testDeepPrototype() throws IOException, ClassNotFoundException {
        System.out.println("===========↓↓↓原型模式：深克隆，测试开始↓↓↓===========");

        Monkey deepMonkey = (Monkey) monkey.deepClone();
        System.out.println("大圣本尊的生日是：" + monkey.getBirthDate());
        System.out.println("深克隆大圣的生日是：" + deepMonkey.getBirthDate());
        System.out.println("大圣本尊和深克隆大圣是否为同一个对象? " + (monkey == deepMonkey));
        // 深克隆中引用的对象也进行了克隆，指向了新的对象，所以本尊和克隆体拿的不是同一个金箍棒。
        System.out.println("大圣本尊的金箍棒和深克隆大圣的金箍棒是否为同一个对象? " + (monkey.getGoldRingedStaff() == deepMonkey.getGoldRingedStaff()));

        System.out.println("= = = = ↑↑↑原型模式：深克隆，测试结束↑↑↑ = = = =");
    }
}
